feat: Volume Boost setting with system LoudnessEnhancer (#88) - #134
Merged
Conversation
Adds a new Settings row "Volume Boost" under the Audio subsection that cycles through 0 / 3 / 6 / 9 / 12 / 15 dB. 0 dB is the default and attaches no effect. Above 0 dB, the player creates an Android `android.media.audiofx.LoudnessEnhancer` bound to the ExoPlayer audio session and applies the target gain. Useful for content whose source audio is very quiet relative to the user's TV/speaker setup \u2014 repeatedly requested in #88 and comparable to the volume boost feature in Debrify TV that the OP referenced. Changes: - `SettingsUiState` / `SettingsViewModel`: new `volumeBoostDb: Int` field. Stored as a string in DataStore via `profileManager.profileStringKey("volume_boost_db")` because ProfileManager has no int helper. Parsed back to Int on read with a 0-15 clamp. `cycleVolumeBoost()` mutator advances through the steps and triggers cloud sync. - `SettingsScreen`: new `Audio` subsection at the bottom of General (below `Network`) containing a single `SettingsRow` for "Volume Boost". The row is placed at `focusedIndex == 14` so no existing indices shift. Both the auto-scroll max-index and the D-pad-down max-index clamps are bumped from 13 to 14. The Enter handler maps `14 -> viewModel.cycleVolumeBoost()`. DNS Provider stays at index 13. - `PlayerUiState` / `PlayerViewModel`: new `volumeBoostDb: Int` field, loaded from the same DataStore key during `loadDetails` initialization. - `PlayerScreen`: new `DisposableEffect(uiState.volumeBoostDb, exoPlayer.audioSessionId)` that creates a `LoudnessEnhancer` when targetDb > 0 and the session id is valid, sets target gain in millibels (dB * 100), enables the effect, and releases it on dispose. Wrapped in try/catch because some Android TV devices reject audio-session effects when HDMI passthrough is enabled for DTS/AC3 \u2014 we fail silently and the user gets unboosted audio but playback still works. - `CloudSyncRepository`: `volumeBoostDb` added to `CloudProfileSettings`, `volumeBoostDbKeyFor(profileId)` helper, push/pull wiring so the setting syncs across devices. Default is 0 so existing users see no change. Stored as string via profileStringKeyFor for the same reason as the SettingsViewModel side. Cap: +15 dB (1500 millibels). Higher values tend to introduce audible distortion on already-compressed streaming audio. The LoudnessEnhancer class supports more but we intentionally don't expose it. This PR touches `SettingsScreen.kt`, `SettingsViewModel.kt`, and `CloudSyncRepository.kt` which PR #131 (Hide Budget, #72) also modifies. Both PRs add a new settings row with different indices and different fields in `CloudProfileSettings`. Whoever merges second will need a small rebase to resolve: - General section max-index should become 15 items (max 15) with both rows present. - `CloudProfileSettings` needs both `showBudget` and `volumeBoostDb` fields. - The Enter handler needs both `13 -> cycleVolumeBoost` and `14 -> openDnsProviderPicker` if #131 lands first, or an additional `15 -> setShowBudget` entry if this PR lands first. The conflict is purely additive and both PRs can coexist on main. Closes #88
ProdigyV21
force-pushed
the
feat/volume-boost
branch
from
April 5, 2026 14:00
9863c77 to
26b850e
Compare
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #88.
Adds a Settings row General > Audio > Volume Boost that cycles through
0 / 3 / 6 / 9 / 12 / 15 dB. 0 dB is the default and attaches no effect. Above 0 dB, the player creates an Androidandroid.media.audiofx.LoudnessEnhancerbound to the ExoPlayer audio session and applies the target gain (dB * 100 millibels).Useful for content whose source audio is very quiet relative to the user's TV/speaker setup \u2014 repeatedly requested in #88 and comparable to Debrify TV's volume boost feature that the OP referenced.
Plumbing
volumeBoostDb: Int. Stored as a string in DataStore (ProfileManager has no int helper) and parsed back with a 0-15 clamp.cycleVolumeBoost()mutator cycles through the steps and triggers cloud sync.Audiosubsection at the bottom of General (belowNetwork) containing a singleSettingsRowfor Volume Boost. Placed atfocusedIndex == 14so no existing indices shift. Max-index clamps bumped from 13 to 14. DNS Provider stays at index 13.volumeBoostDb: Int, loaded atloadDetailsinit from the same DataStore key.DisposableEffect(uiState.volumeBoostDb, exoPlayer.audioSessionId)that creates aLoudnessEnhancerwhentargetDb > 0and the session id is valid, sets target gain, enables, and releases on dispose. Wrapped in try/catch because some Android TV devices reject audio-session effects when HDMI passthrough is on for DTS/AC3 \u2014 fails silently and playback still works.volumeBoostDbadded toCloudProfileSettings, newvolumeBoostDbKeyFor(profileId)helper, push/pull wiring.Cap and safety
Max +15 dB (1500 mB). Higher values tend to introduce audible distortion on already-compressed streaming audio, and the LoudnessEnhancer class can support more but we intentionally don't expose it.
Merge-conflict note with PR #131
PR #131 (Show Budget toggle, #72) also modifies
SettingsScreen.kt,SettingsViewModel.kt, andCloudSyncRepository.kt\u2014 both PRs add a new settings row at the end of the General section and a new field inCloudProfileSettings. Whoever merges second will need a small rebase to:showBudgetandvolumeBoostDbtoCloudProfileSettings.The conflict is purely additive. Both features coexist on main.
Risk
Low.
LoudnessEnhanceris a stable AOSP class (API 19+, and minSdk on ARVIO is well above that). Default 0 means no effect instance is created, so non-boosted users see zero overhead. The try/catch handles the known HDMI passthrough edge case.